User blog:Hseiken/Music Created by Game Actions
I had an idea a couple of days ago that seems to be working so if anyone is interested in creating 'algorithmic music' in Petitcom tied to gameplay elements, I'll offer a bit of what I did to get it working. So most games have a tiny loop in which the main game runs. You'll have an arrangement like this pseudocode below: @MAINLOOP GOSUB @HANDLEINPUT GOSUB @DOSTUFFBASEDONINPUT GOSUB @UPDATETHESCREEN VSYNC 1 GOTO @MAINLOOP This is a typical game program flow that most programmers will take. What I've found is that depending on this arrangement, you can add non MML music that works on a tempo/beat timer combination which sets flags on events happening in the game. Basically, the code above would include an additonal sub of @DOMUSICSTUFF. Inside this sub, you would have this pseudocode: @DOMUSICSTUFF TICK = TICK + 1 IF TICK = TEMPO THEN TICK = 1 '<--IN MUSIC, 1 IS EASIER TO DEAL WITH THAN 0 IF GAMEFLAG1 = 1 AND TICK = 1 THEN BEEP 32:GAMEFLAG1 = 0 IF GAMEFLAG2 = 1 AND TICK = 8 THEN BEEP 34:GAMEFLAG2 = 0 RETURN At the beginning of your program you'll need to define TEMPO. This will be your actual beat. Think of this as the kick in a typical techno sound that holds the music together. TEMPO should be an EVEN NUMBER! If you have an odd number, you'll get strange swing and mis-timed musical elements. Gameflags should be set to 1 inside the subs controlling the event. For instance, in my own project which includes a Tetris-type fall block game, I have a 4/4 kick play as pieces drop. When lines are cleared, rhythmically a crash cymbol sounds. New pieces put onto the playfield play a short SFX in time. Rotating the piece adds an extra distorted kick, moving the piece down faster plays the kick at double time. This is all independent of the actual tetris pieces moving and such so there's no lag in the gameplay, but it still creates the musical rhythms you hear based on the events. You can use this for any elements. If you want to create melodies in this method, you can have a BEAT counter. Everytime TEMPO is reached, add +1 to BEAT and use the BEAT + TICK to determine notes to be played at that time. Be careful for slightly intensive subroutines in your program as these will create jumps or delays in your music. To combat this, periodically call the music sub somewhere in a hefty array check and other suspect elements. Doing this will give the impression that the music is operating independently completely since the music won't slow down while large calculations are happening. As well, possibly moving VSYNC to the music handling sub can make sure that it doesn't run off course. Experiment with it without gameplay elements to figure out how to control it before sticking it in a game to see if it's something you wish to do. Don't forget, you can run a BEEP command straight from the console outside of the code editor to audition sounds. The downside to this method is that you cannot create special instruments or change the length of notes, so be aware of this before using this method. Once I get a grasp on MML (still looking for a good tutorial!) I'll attempt to do this same method via MML which would allow changing note lengths, creating custom waveforms, etc. Until next time, keep on programming! Category:Blog posts